package com.cqupt.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.exception.BusinessException;
import com.cqupt.mapper.WordMapper;
import com.cqupt.model.pojo.SysUser;
import com.cqupt.model.pojo.UserWord;
import com.cqupt.model.pojo.Word;
import com.cqupt.model.vo.ResultCodeEnum;
import com.cqupt.service.UserWordService;
import com.cqupt.mapper.UserWordMapper;
import com.cqupt.utils.AuthContextUtil;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


@Service
public class UserWordServiceImpl extends ServiceImpl<UserWordMapper, UserWord>
        implements UserWordService {

    @Resource
    private UserWordMapper userWordMapper;


    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private WordMapper wordMapper;

    @Override
    public void unknown(int wordId, int bookId) {
        Integer userId = AuthContextUtil.get().getId();
        LambdaQueryWrapper<UserWord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserWord::getUserId, userId);
        wrapper.eq(UserWord::getBookId, bookId);
        wrapper.eq(UserWord::getWordId, wordId);
        UserWord userWord = userWordMapper.selectOne(wrapper);
        if (ObjectUtil.isNull(userWord)) {
            UserWord one = new UserWord();
//            one.setUnknown(1);
            one.setUserId(userId);
            one.setBookId(bookId);
            one.setWordId(wordId);
            userWordMapper.insert(one);
        } else {
//            userWord.setUnknown(1);
            userWordMapper.updateById(userWord);
        }
    }

    @Override
    public void learn(int wordId, int bookId) {

    }

    @Override
    public List<Word> getAllUnknown() {
        int userId = AuthContextUtil.get().getId();
        return wordMapper.getAllUnknown(userId);
    }

    @Override
    public List<Word> getAllLearned(int bookId) {
        int userId = AuthContextUtil.get().getId();
        return wordMapper.getAllLearned(userId, bookId);
    }

    @Override
    @Transactional
    public void rest(int bookId, int count) {
        Integer userId = AuthContextUtil.get().getId();
        String json = stringRedisTemplate.opsForValue().get(userId + ":" + bookId);
        List<Word> list = JSON.parseArray(json, Word.class);
        if (list.size() > count) {
            list.subList(0, count).clear();
            stringRedisTemplate.opsForValue().set(userId + ":" + bookId, JSON.toJSONString(list));
        } else {
//            list.subList(0, list.size()).clear();
//            stringRedisTemplate.opsForValue().set(userId + ":" + bookId, JSON.toJSONString(list));
            stringRedisTemplate.delete(userId + ":" + bookId);
        }

//        long time = System.currentTimeMillis();
//
//        List<Word> review = wordMapper.getReview(userId, bookId, time);
//        if (!ObjectUtil.isEmpty(review)) {
//            stringRedisTemplate.opsForValue().set("review:" + userId + ":" + bookId, JSON.toJSONString(review));
//        }
    }

    @Override
    public List<Word> again(int bookId, int count) {
        rest(bookId, count);
        Integer userId = AuthContextUtil.get().getId();
        String json = stringRedisTemplate.opsForValue().get(userId + ":" + bookId);
        if (StrUtil.isEmpty(json)) {
            throw new BusinessException(ResultCodeEnum.DATA_ERROR);
        }
        List<Word> list = JSON.parseArray(json, Word.class);
        if (Objects.isNull(list)) {
            throw new BusinessException(ResultCodeEnum.DATA_ERROR);
        }
        if (list.size() >= count) {
            return list.stream().limit(count).toList();
        }
        return list;
    }

}




